home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 2.1 / Amiga Developer CD v2.1.iso / Reference / DevCon / Washington_1988 / DevCon88.1 / JimmDemos / DemoSource / steali.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-27  |  3.6 KB  |  150 lines

  1. /* steali.c -- install and remove C-language input handler
  2.  * Copyright (c) 1988, I and I Computing, and Commodore-Amiga, Inc.
  3.  *
  4.  *
  5.  * Executables based on this information may be used in software
  6.  * for Commodore Amiga computers.  All other rights reserved.
  7.  *
  8.  * This information is provided "as is"; no warranties are made.
  9.  * All use is at your own risk, and no liability or responsibility is assumed.
  10.  */
  11.  
  12. #include "sysall.h"
  13.  
  14. #define TEST 0
  15.  
  16. #if TEST
  17.  
  18. /* Test Input Handler
  19.  * this fellow runs as the input.device task.  His context is set
  20.  * up so that he can access global data and other functions,
  21.  * but it must be remembered that no DOS functions may be used.
  22.  */
  23. struct InputEvent *
  24. customHandler(input_event)
  25. struct InputEvent *input_event;
  26. {
  27.     extern long int shared_count;    /* global data    */
  28.     struct InputEvent *ie;
  29.  
  30.     /* count 'em    */
  31.  
  32.     for (ie = input_event; ie; ie = ie->ie_NextEvent)
  33.     {
  34.         shared_count++;
  35.     }
  36.  
  37.     return (input_event);
  38. }
  39.  
  40. /* indicator variable shared by my task and my input handler */
  41. long int    shared_count = 0;
  42.  
  43. main()
  44. {
  45.     LONG installInputHandler();
  46.  
  47.     printf("try to install my handler\n");
  48.  
  49.     /* install my input handler at priority greater than Intuition */
  50.     installInputHandler( customHandler, 51);
  51.  
  52.     /* wait for something to happen    */
  53.     printf("handler installed, press rtc:");
  54.     fflush(stdout);
  55.     getchar();
  56.  
  57.     /* remove my fellow    */
  58.     extractInputHandler();
  59.  
  60.     printf("there were %ld input events counted by our handler\n", shared_count);
  61. }
  62.  
  63. #endif    TEST
  64.  
  65. struct MsgPort        *indev_port = NULL;
  66. struct IOStdReq        *indev_req =  NULL;
  67. struct Interrupt    handler_interrupt;
  68.  
  69. /* 
  70.  * opens input.device, installs an input handler
  71.  * that calls c_handler in a C friendly way
  72.  *
  73.  * NOTE: returns WaitIO() return value, which is
  74.  * 0 if OK.
  75.  */
  76. LONG
  77. installInputHandler( c_handler, priority)
  78. struct InputEvent    *(*c_handler)();
  79. int                    priority;
  80. {
  81.     LONG    handlerInterface();        /* asm-C interface code    */
  82.  
  83.     indev_port = CreatePort( NULL, 0L );
  84.     indev_req =  CreateStdIO( indev_port );
  85.  
  86.     OpenDevice( "input.device", 0L, indev_req, 0L );
  87.  
  88.     /* set up interrupt struct, use C-handler address as the data    */
  89.     handler_interrupt.is_Code = (VOID (*)()) handlerInterface;
  90.     handler_interrupt.is_Data = (APTR) c_handler;
  91.     handler_interrupt.is_Node.ln_Pri = priority;
  92.  
  93.     indev_req->io_Command = IND_ADDHANDLER;
  94.     indev_req->io_Data =    (APTR) &handler_interrupt;
  95.  
  96.     /* install the sucker    */
  97.     SendIO( indev_req );
  98.     return ( WaitIO( indev_req ) );
  99. }
  100.  
  101. /*
  102.  * better be sure that installInputHandler() worked and is
  103.  * in effect.
  104.  */
  105. extractInputHandler()
  106. {
  107.     indev_req->io_Command = IND_REMHANDLER;
  108.  
  109.     SendIO( indev_req );
  110.     WaitIO( indev_req );
  111.  
  112.     CloseDevice( indev_req );        /* close input.device    */
  113.     DeleteStdIO( indev_req );
  114.     DeletePort( indev_port );
  115. }
  116.  
  117. /*
  118.  * what follows is an assembly language fragment necessary (perhaps
  119.  * more than necessary) to call a small model Aztec C program from
  120.  * the input device.
  121.  *
  122.  * Aztec C has a different register convention than the system code,
  123.  * and small model requires that a base address pointer be set
  124.  * up in register A4.  Also, the parameter to an input handler
  125.  * must be pushed on the stack for a C routine to use it.
  126.  */
  127.  
  128. #asm
  129.     cseg
  130.     public    _handlerInterface
  131.     public    _geta4
  132.  
  133.     ; ---    NEVER FORGET that this runs as the input.device task
  134.  
  135. _handlerInterface:
  136.     ; ---    pointers to linked list of input events in a0, is_Data in a1
  137.     ; ---    is_Data is simply the address of the C handler
  138.  
  139.     ; ---    protect everything necessary (and more?)
  140.     movem.l    d2/d3/d4-d7/a2-a6,-(sp)
  141.     jsr        _geta4        ; set up context for handler (Aztec C function)
  142.     move.l    a0,-(sp)    ; push input event list
  143.     jsr        (a1)        ; jump to real C handler
  144.     addq.l    #4,a7        ; pop argument
  145.     movem.l    (sp)+,d2/d3/d4-d7/a2-a6
  146.  
  147.     rts
  148. #endasm
  149.  
  150.